package com.tencent.txcc.service.impl;

import com.tencent.txcc.domain.CourseDoc;
import com.tencent.txcc.dto.CourseSearchDto;
import com.tencent.txcc.repository.CourseRepository;
import com.tencent.txcc.result.PageList;
import com.tencent.txcc.service.IESService;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

@Service
public class RSServiceImpl implements IESService {

    @Autowired
    private CourseRepository courseRepository;

    @Override
    public void courseEsAdd(CourseDoc courseDoc) {
        courseRepository.save(courseDoc);
    }

    @Override
    public void courseEsDel(Long id) {
        courseRepository.deleteById(id);
    }

    @Override
    public PageList<CourseDoc> courseSearch(CourseSearchDto courseSearchDto) {
        // 创建原生的条件构造器对象
        NativeSearchQueryBuilder nativeSearchQueryBuilder = new NativeSearchQueryBuilder();

        // 设置查询条件
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();

        // 判断传入的Keyword是否有
        if (!StringUtils.isEmpty(courseSearchDto.getKeyword())) {
            // 如果Keyword有值，分词查询,通过传入的关键字对比CourseSearchDto的课程名字name查询
            boolQueryBuilder.must(QueryBuilders.matchQuery("name", courseSearchDto.getKeyword()));
        }

        // 判断传入的课程类型是否有
        if (courseSearchDto.getCourseTypeId() != null) {
            // 如果课程类型有值，分词查询,通过传入的关键字对比CourseSearchDto的课程类型名字courseTypeId查询
            boolQueryBuilder.filter(QueryBuilders.matchQuery("courseTypeId", courseSearchDto.getCourseTypeId()));
        }

        // 判断是否收费
        if (!StringUtils.isEmpty(courseSearchDto.getChargeName())) {
            // 如果Keyword有值，分词查询,通过传入的关键字对比CourseSearchDto的课程名字name查询
            boolQueryBuilder.filter(QueryBuilders.matchQuery("charge", courseSearchDto.getChargeName()));
        }

        // 判断是否传入等级
        if (!StringUtils.isEmpty(courseSearchDto.getGradeName())) {
            // 如果Keyword有值，分词查询,通过传入的关键字对比CourseSearchDto的课程名字name查询
            boolQueryBuilder.filter(QueryBuilders.matchQuery("gradeName", courseSearchDto.getGradeName()));
        }

        // 判断传入的价格区间最大值是否有
        if (courseSearchDto.getPriceMax() != null) {
            // 如果课程类型有值，分词查询,通过传入的PriceMax对比price查询
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").lte(courseSearchDto.getPriceMax()));
        }

        // 判断传入的价格区间最小值是否有
        if (courseSearchDto.getPriceMin() != null) {
            // 如果课程类型有值，分词查询,通过传入的PriceMin对比price查询
            boolQueryBuilder.filter(QueryBuilders.rangeQuery("price").gte(courseSearchDto.getPriceMin()));
        }

        if (!StringUtils.isEmpty(courseSearchDto.getSortField()) && !StringUtils.isEmpty(courseSearchDto.getSortType())){
            // 判断传入的排序类型
            SortOrder sortOrder = "asc".equalsIgnoreCase(courseSearchDto.getSortType()) ? SortOrder.ASC : SortOrder.DESC;

            // 排序通过传入的SortField排序字段进行降序排列                                                    动态排序
            nativeSearchQueryBuilder.withSort(SortBuilders.fieldSort(courseSearchDto.getSortField()).order(sortOrder));

        }

        nativeSearchQueryBuilder.withQuery(boolQueryBuilder);

        // 设置分页条件
        nativeSearchQueryBuilder.withPageable(PageRequest.of(courseSearchDto.getPage() - 1, courseSearchDto.getRows()));

        // 根据条件构造器创建条件对象
        NativeSearchQuery build = nativeSearchQueryBuilder.build();

        // 通过courseRepository的search方法，先找到返回的分页的数据
        Page<CourseDoc> page = courseRepository.search(build);

        return new PageList<>(page.getTotalElements(), page.getContent());
    }
}
